package com.zl.quickdoc.format.impl;

import java.io.File;
import java.io.FileOutputStream;
import java.util.List;

import org.apache.commons.lang3.StringUtils;

import com.zl.quickdoc.constant.QuickDocC;
import com.zl.quickdoc.format.FreemarkerTemplater;
import com.zl.quickdoc.format.IApiFormat;
import com.zl.quickdoc.model.ApiAction;
import com.zl.quickdoc.model.ApiDocument;
import com.zl.quickdoc.model.ApiField;
import com.zl.quickdoc.model.ApiModule;
import com.zl.quickdoc.model.DocCfgParam;
import com.zl.quickdoc.utils.ParserJavaUtils;

/**
 * @author zhouliang
 */
public class ApiFormatJavaclass extends ApiFormatBase implements IApiFormat {

    
    private FreemarkerTemplater templater = new FreemarkerTemplater("classpath:"+QuickDocC.TEMPLATE_ROOT+QuickDocC.TEMPLATE_JAVA);
    
    @Override
    public String formatType() {
        return QuickDocC.DOC_TYPE_JAVA;
    }
    @Override
    public String templateName() {
        return QuickDocC.TEMPLATE_JAVA;
    }
    
    @Override
    public void format(ApiDocument apiDoc,DocCfgParam cfg) throws Exception{
        File tFile = getTemplatePath(cfg,templateName());
        if(tFile.exists()&&tFile.isFile()) {
            templater.setPath(tFile.getPath());
        }
        
        for(int i=0;i<apiDoc.getApiModules().size();i++){
            ApiModule x = apiDoc.getApiModules().get(i);
            File f = new File(cfg.getApiPath() + File.separator + QuickDocC.CHILDREN_PATH_TESTS + File.separator 
                    +x.getClassName().replaceAll("^package |\\."+x.getSimpleName()+"$", "").replace(".", "/"));
            if(!f.exists()||!f.isDirectory()){
                f.mkdirs();
            }
            x.getApiActions().stream().forEach(ax->getRequestJsonJava(ax));
            x.setClassName(x.getSimpleName()+"Test");
            String s = templater.processString(x);
            File outfile = new File(f.getPath(),x.getSimpleName()+"Test.java");
            FileOutputStream out = new FileOutputStream(outfile);
            writeDoc(s, out);
            if(i==0) {
                apiDoc.setOutputPath(outfile.getAbsolutePath());
            }
        }
    }
    
    private void getRequestJsonJava(ApiAction ax) {
        if(ax.getRequestVoid()) {
            ax.setRequestJsonJava("");
            return;
        }
        StringBuilder bufsimple=new StringBuilder();
        setFormJavaJson(bufsimple, ax.getReqParam(),"");
        String[] lines = bufsimple.toString().replaceAll("^\n|\n$", "").split("\n");
        ax.setRequestJsonJava(StringUtils.join(lines," \"+\n        \""));
    }
    private void setFormJavaJson(StringBuilder buf , List<ApiField> fields,String blankstr) {
        if(fields==null || fields.isEmpty()){
            return;
        }

        int idx=0;
        for(ApiField fieldx:fields){
            List<ApiField> childrens = fieldx.getChildren();
            if(childrens!=null&&childrens.size()>0){
                if(!fieldx.getAnonymousFlag() && StringUtils.isNotBlank(fieldx.getFactName())) {
                        buf.append("\n"+blankstr+"'"+fieldx.getName()+"': ");
                }else {
                    buf.append(!fieldx.getSimpleValueFlag()?"\n" +blankstr:"");
                }
                if("Arrays".equals(fieldx.getFactType())){
                    buf.append("[");
                }
                else if("Objects".equals(fieldx.getFactType()) || "Map".equals(fieldx.getFactType())){
                    buf.append("{");
                }
                setFormJavaJson(buf, childrens, !fieldx.getSimpleValueFlag()?blankstr + "  ":"");
                if("Arrays".equals(fieldx.getFactType())){
                    buf.append((!fieldx.getSimpleValueFlag()?"\n" +blankstr:"")+"]");
                }
                else if("Objects".equals(fieldx.getFactType()) || "Map".equals(fieldx.getFactType())){
                    buf.append("\n"+blankstr+"}");
                }
                if(idx<fields.size()-1){
                    buf.append(", ");
                }
            }else{
                if(!fieldx.getAnonymousFlag() && StringUtils.isNotBlank(fieldx.getFactName())) {
                    buf.append(String.format("\n"+blankstr+"'%s': ",fieldx.getName()));
                }else{
                    buf.append(!fieldx.getSimpleValueFlag()?"\n"+blankstr:"");
                }
                if("Objects".equals(fieldx.getFactType())){
                    if(StringUtils.isNotBlank(fieldx.getDefaultValue())){
                        if(fieldx.getDefaultValue().startsWith("\"")){
                            buf.append(fieldx.getDefaultValue().replaceAll("^\"|\"$", ""));
                        }else {
                            buf.append(ParserJavaUtils.defaultValueHandler(fieldx));
                        }
                    }else{
                        buf.append("{}");
                    }
                }else{
                    buf.append(ParserJavaUtils.defaultValueHandler(fieldx).replaceAll("^\"|\"$", ""));
                }
                if(idx<fields.size()-1){
                    buf.append(", ");
                }
            }
            idx++;
        }
    }
}
